package com.zyf.chapter01.refactor;

import com.zyf.chapter01.refactor.util.IdGenerator;
import com.zyf.chapter01.refactor.util.RedisDistributedLock;
import com.zyf.chapter01.refactor.util.STATUS;
import com.zyf.chapter01.refactor.util.WalletRpcService;

import javax.transaction.InvalidTransactionException;

/**
 * 简化的电商系统交易类
 * 用来记录每笔订单交易的情况
 * @author yifeng
 */
public class Transaction_Old {
    private String id;
    private Long buyerId; // 买方
    private Long sellerId; // 卖方
    private Long productId;
    private String orderId;
    private Long createTimestamp;
    private Double amount; // 总量
    private Long status;
    private String walletTransactionId;

    public String getId() {
        return id;
    }

    public Long getBuyerId() {
        return buyerId;
    }

    public Long getSellerId() {
        return sellerId;
    }

    public Long getProductId() {
        return productId;
    }

    public String getOrderId() {
        return orderId;
    }

    public Long getCreateTimestamp() {
        return createTimestamp;
    }

    public Double getAmount() {
        return amount;
    }

    public Long getStatus() {
        return status;
    }

    public String getWalletTransactionId() {
        return walletTransactionId;
    }



    private static String ID_PREFIX = "t_";
    private static long FOURTEEN_DAY = 1209600000;

    public Transaction_Old(String preAssignedId, Long buyerId, Long sellerId, Long productId, String orderId) {
        if (preAssignedId != null && !preAssignedId.isEmpty()) {
            this.id = preAssignedId;
        } else {
            this.id = IdGenerator.generateTransactionId();
        }
        if (!this.id.startsWith(ID_PREFIX)) {
            this.id = ID_PREFIX + preAssignedId;
        }

        this.buyerId = buyerId;
        this.sellerId = sellerId;
        this.productId = productId;
        this.orderId = orderId;
        this.status = STATUS.TO_BE_EXECUTED;
        this.createTimestamp = System.currentTimeMillis();
    }

    /**
     * 负责执行转账操作
     * @return
     * @throws InvalidTransactionException
     */
    public boolean execute() throws InvalidTransactionException {
        boolean check = buyerId == null || (sellerId == null || amount.floatValue() < 0.0);
        if (check) {
            throw new InvalidTransactionException("参数值:buyerId、sesserId 不能为空");
        }
        if (status.equals(STATUS.EXECUTED)) return true;
        boolean isLocked = false;
        try {
            boolean isLock = RedisDistributedLock.getSingletonIntance().lockTransction(id);
            if (!isLock)
                return false; // 锁定未成功，放回 false， job 兜底执行
            if (status == STATUS.EXECUTED) return true; // double check

            long executionInvokedTimestamp = System.currentTimeMillis();
            if (executionInvokedTimestamp - createTimestamp > FOURTEEN_DAY) {
                this.status = STATUS.EXPIRED;
                return false;
            }
            if (!isLock) {
                return  false; // 锁定未成功，返回 false，job 兜底之下
            }
            // 通过调用该服务，执行真正的转账操作
            WalletRpcService walletRpcService = new WalletRpcService();
            String walletTransactionId = walletRpcService.moveMoney(id, buyerId, sellerId, amount);
            if (walletRpcService != null) {
                this.walletTransactionId = walletTransactionId;
                this.status = STATUS.EXECUTED;
                return true;
            } else {
                this.status = STATUS.FAILD;
                return false;
            }
        } finally {
            if (isLocked) {
                RedisDistributedLock.getSingletonIntance().unlockTranscation(id);
            }
        }

    }
}
